package deptimpl

import (
	"context"
	"go-caipu/pkg/services/admin/dept"
	"go-caipu/pkg/services/admin/model"
	"go-caipu/pkg/util"
	"gorm.io/gorm"
	"sort"
	"time"
)

type Service struct {
	store store
}

func ProvideService(db *gorm.DB) (*Service, error) {
	sql := ProvideStore(db)
	s := &Service{
		store: &sql,
	}
	return s, nil
}

func (s Service) Get(ctx context.Context, c dept.GetDeptCommand) (dept.Dept, error) {
	result, err := s.store.Get(ctx, c)
	if err != nil {
		return dept.Dept{}, nil
	}
	return generateDto(result), nil
}

func (s Service) Insert(ctx context.Context, item dept.Dept) error {
	sys := model.SysDept{
		DeptName: item.DeptName,
		ParentId: item.ParentId,
		DeptPath: item.DeptPath,
		Sort:     item.Sort,
		Leader:   item.Leader,
		Phone:    item.Phone,
		Email:    item.Email,
		Status:   item.Status,
		Remark:   item.Remark,
	}
	sys.CreatedAt = time.Now()
	return s.store.Insert(ctx, sys)
}
func (s Service) Update(ctx context.Context, item dept.Dept) error {
	dept, err := s.store.Get(ctx, dept.GetDeptCommand{Id: util.Int64ToString(item.DeptId)})
	if err != nil {
		return err
	}
	dept.DeptName = item.DeptName
	dept.ParentId = item.ParentId
	dept.Sort = item.Sort
	dept.Leader = item.Leader
	dept.Phone = item.Phone
	dept.Email = item.Email
	dept.Status = item.Status
	dept.UpdatedAt = time.Now()
	dept.Remark = item.Remark
	return s.store.Update(ctx, dept)
}

func (s Service) Remove(ctx context.Context, id dept.DeleteDeptCommand) error {
	return s.store.Remove(ctx, id)
}

func (s Service) GetDeptTreeList(ctx context.Context, cmd dept.GetDeptTreeListCommand) (m []*dept.Dept, err error) {
	depts, err := s.store.GetDeptList(ctx, cmd)
	if err != nil {
		return nil, err
	}

	//存储部门数据
	deptMap := make(map[int64]*dept.Dept)
	for _, item := range depts {
		s := generateDto(item)
		deptMap[item.DeptId] = &s
	}

	return buildTree(deptMap), nil
	//for _, item := range depts {
	//	if item.ParentId != 0 {
	//		continue
	//	}
	//
	//	info := s.deptPageCall(depts, item)
	//	m = append(m, info)
	//}

	return
}

// SortDeptsByDeptID 接受部门指针切片并根据DeptID排序
func SortDeptsByDeptID(depts []*dept.Dept) {
	sort.SliceStable(depts, func(i, j int) bool {
		return depts[i].Sort < depts[j].Sort
	})
}
func sortChildren(dept *dept.Dept) {
	if dept.Children != nil {
		SortDeptsByDeptID(dept.Children) // 使用我们的排序函数
		for _, child := range dept.Children {
			sortChildren(child) // 递归排序
		}
	}
}
func buildTree(depts map[int64]*dept.Dept) []*dept.Dept {
	var roots = make([]*dept.Dept, 0)
	for _, item := range depts {
		if item.ParentId == 0 {
			roots = append(roots, item)
		} else {
			if depts[item.ParentId] == nil {
				roots = append(roots, item)
				continue
			}
			if depts[item.ParentId].Children == nil {
				depts[item.ParentId].Children = []*dept.Dept{}
			}
			depts[item.ParentId].Children = append(depts[item.ParentId].Children, item)
		}
	}
	// 对根节点进行排序
	SortDeptsByDeptID(roots)
	// 递归排序子节点
	for _, root := range roots {
		sortChildren(root)
	}
	return roots
}

// deptPageCall 分页崆构造
//func (s Service) deptPageCall(depts []model.SysDept, curr model.SysDept) (menu dept.Dept) {
//	min := make([]dept.Dept, 0)
//	menu = generateDto(curr)
//	for _, item := range depts {
//		if item.ParentId != curr.DeptId {
//			continue
//		}
//		child := s.deptPageCall(depts, item)
//		min = append(min, child)
//	}
//	menu.Children = min
//	return
//}

// generateDto 对象转换
func generateDto(item model.SysDept) (result dept.Dept) {
	result = dept.Dept{}
	result.DeptId = item.DeptId
	result.DeptName = item.DeptName
	result.ParentId = item.ParentId
	result.DeptPath = item.DeptPath
	result.Sort = item.Sort
	result.Leader = item.Leader
	result.Phone = item.Phone
	result.Email = item.Email
	result.Status = item.Status
	result.Remark = item.Remark
	result.CreatedAt = item.CreatedAt.Format("2006-01-02 15:04:05")
	result.UpdatedAt = item.UpdatedAt.Format("2006-01-02 15:04:05")

	result.CreateUserString = item.CreateUser.NickName
	result.UpdateUserString = item.UpdateUser.NickName
	return result
}

// GetDeptTree 前端部门树的内容
func (s Service) GetDeptTree(ctx context.Context, cmd dept.GetDeptTreeListCommand) (m []dept.TreeDept, err error) {
	deptList, err := s.store.GetDeptList(ctx, cmd)
	if err != nil {
		return nil, err
	}
	m = make([]dept.TreeDept, 0)
	for _, item := range deptList {
		if item.ParentId != 0 {
			continue
		}
		e := dept.TreeDept{
			Key:      util.Int64ToString(item.DeptId),
			Sort:     item.Sort,
			Title:    item.DeptName,
			ParentId: item.ParentId,
		}
		m = append(m, deptTreeCall(deptList, e))
	}
	return
}

// deptTreeCall 扩展前端树子树内容
func deptTreeCall(deptList []model.SysDept, curr dept.TreeDept) dept.TreeDept {
	min := make([]dept.TreeDept, 0)
	for _, item := range deptList {
		if curr.Key != util.Int64ToString(item.ParentId) {
			continue
		}
		mi := dept.TreeDept{
			Key:      util.Int64ToString(item.DeptId),
			Sort:     item.Sort,
			Title:    item.DeptName,
			ParentId: item.ParentId,
		}
		ms := deptTreeCall(deptList, mi)
		min = append(min, ms)
	}
	curr.Children = min
	return curr
}

// GetDeptSelect 获取部门下拉框内容(插件使用）
func (s Service) GetDeptSelect(ctx context.Context) (result []dept.SelectDept, err error) {
	cmd := dept.GetDeptTreeListCommand{Status: "1"}
	deptList, err := s.store.GetDeptList(ctx, cmd)
	if err != nil {
		return nil, err
	}
	result = make([]dept.SelectDept, 0)
	for _, item := range deptList {
		e := dept.SelectDept{
			ID:       util.Int64ToString(item.DeptId),
			ParentId: util.Int64ToString(item.ParentId),
			Name:     item.DeptName,
		}
		result = append(result, e)
	}
	return
}

// GetDeptAndChildrenIds 获取部门及子部门ID列表(包括本部门）
// fix:后续再增加缓存优化
func (s Service) GetDeptAndChildrenIds(ctx context.Context, deptID int64) ([]int64, error) {
	// 1. 查询所有部门
	cmd := dept.GetDeptTreeListCommand{Status: "1"}
	allDepts, err := s.store.GetDeptList(ctx, cmd)
	if err != nil {
		return nil, err
	}

	// 2. 构建 parentID 到子部门的映射
	deptMap := make(map[int64][]int64)
	for _, dept := range allDepts {
		deptMap[dept.ParentId] = append(deptMap[dept.ParentId], dept.DeptId)
	}

	// 3. 递归获取所有子部门ID
	result := make([]int64, 0)
	getChildrenIDs(deptID, deptMap, &result)

	return result, nil
}
func getChildrenIDs(deptID int64, deptMap map[int64][]int64, result *[]int64) {
	*result = append(*result, deptID)
	//获取并处理所有子部门
	for _, childID := range deptMap[deptID] {
		getChildrenIDs(childID, deptMap, result)

	}
}
